package unibz.thaison.iosa;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;

import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.view.Viewable;

@Path("/screen")
public class ScreenService {
	private ScreenManager manager = ScreenManager.getInstance();
	static String weatherLocation = "http://api.wunderground.com/api/ae37f61e874f3512/conditions/q/IT/Bolzano.json";
	static String userLocation = "http://localhost:8080/iosa_rest/rest/user";
	static String TrelloLocation = "https://api.trello.com/1/boards/50f0a72e7fb3446f0b005268?actions=all&actions_limit=3&cards=all&lists=all&members=all&member_fields=all&checklists=all&fields=all&key=a23d9d51e37e3dc9e6d2fac4fae598e4&token=4426b7c2bda7a9a09fe8cc3fb178a9696f7296d571a9c40e2310a015eb9bbe5b";
	//static String TrelloLocation = "https://api.trello.com/1/boards/4d5ea62fd76aa1136000000c";
	//static String TrelloLocation = "https://trello.com/board/soa/50f0a72e7fb3446f0b005268/board.json";
	
	protected TrelloBoard getTrello() throws Exception 
	{
		TrelloBoard trelloBoard = null;
		
		ClientConfig config = ClientHelper.configureClient();
		Client client = Client.create(config);
		
		WebResource webResource = client.resource(TrelloLocation);
		ClientResponse response = webResource.type(MediaType.APPLICATION_JSON)
											 .accept(MediaType.APPLICATION_JSON)
											 .get(ClientResponse.class);
		
		
        if (response.getClientResponseStatus() == ClientResponse.Status.OK) 
        {
        	trelloBoard = new TrelloBoard();
        	
        	String output = response.getEntity(String.class);
        	JSONObject json = new JSONObject(output);
        	
        	//get board info: id, name, desc
        	trelloBoard.setBoardId(json.getString("id"));
        	trelloBoard.setBoardName(json.getString("name"));
        	trelloBoard.setBoardDescription(json.getString("desc"));
        	trelloBoard.setBoardUrl(json.getString("url"));
        	
        	//get member info: id, fullName, memberType, status, username
        	JSONArray mems = json.getJSONArray("members"); 
        	for (int i = 0; i < mems.length(); i++)
        	{
        		JSONObject mem = mems.getJSONObject(i);
        		Member newMem = new Member();
        		newMem.setId(mem.getString("id"));
        		newMem.setFullname(mem.getString("fullName"));
        		newMem.setMemberType(mem.getString("memberType"));
        		newMem.setStatus(mem.getString("status"));
        		newMem.setUsername(mem.getString("username"));        		
        		trelloBoard.addMember(newMem);        		
        	}
        	
        	//get list info: id, name, cards
        	JSONArray lists = json.getJSONArray("lists");
        	for (int i = 0; i < lists.length(); i++)
        	{
        		JSONObject list = lists.getJSONObject(i);
        		TrelloList newList = new TrelloList(); 
        		newList.setId(list.getString("id"));
        		newList.setName(list.getString("name"));        		
        		trelloBoard.addList(newList);        		
        	}        	
        	
        	//get card info: idList, idMembers, name, desc
        	JSONArray cards = json.getJSONArray("cards");
        	for (int i = 0; i < cards.length(); i++)
        	{
        		JSONObject card = cards.getJSONObject(i);
        		Card newCard = new Card(); 
        		newCard.setIdList(card.getString("idList"));
        		newCard.setName(card.getString("name"));
        		newCard.setDescription(card.getString("desc"));
        		
        		JSONArray idMembers = card.getJSONArray("idMembers");
        		for (int j = 0; j < idMembers.length(); j++)
        		{
        			String idMem = idMembers.getString(i);
        			String name = trelloBoard.getMemberNameById(idMem);
        			newCard.addMemberName(name);
        		}
        		newCard.setParticipants();
        		trelloBoard.getTrelloListById(newCard.getIdList()).addCard(newCard);
        	}
        	
        	//get action info: data, id, member creator, type, date
        	JSONArray actions = json.getJSONArray("actions");
        	for (int i = 0; i < actions.length(); i++)
        	{
        		JSONObject action = actions.getJSONObject(i);
        		Action newAction = new Action();
        		newAction.setData(action.getString("data"));
        		newAction.setId(action.getString("id"));
        		String memCreator = trelloBoard.getMemberNameById(action.getString("idMemberCreator"));
        		newAction.setMemberCreatorName(memCreator);
        		newAction.setType(action.getString("type"));
        		newAction.setDate(action.getString("date"));     
        		
        		trelloBoard.addAction(newAction);
        	}
        }
        return trelloBoard;
	}
	
	protected List<User> getUsers() throws Exception {
		List<User> users = null;
		Client client = Client.create();
		WebResource webResource = client.resource(userLocation);
		ClientResponse response = webResource.type(MediaType.TEXT_PLAIN)
				.accept(MediaType.APPLICATION_JSON)
				.get(ClientResponse.class);
		if (response.getClientResponseStatus() == ClientResponse.Status.OK) {
        	String output = response.getEntity(String.class);
        	ObjectMapper mapper = new ObjectMapper();
        	users = mapper.readValue(output, new TypeReference<List<User>>(){});
        }
        return users;
	}
	
	protected Weather getWeather() throws Exception {
		Weather weather = null;
		Client client = Client.create();
		WebResource webResource = client.resource(weatherLocation);
		ClientResponse response = webResource.type(MediaType.APPLICATION_JSON)
				.accept(MediaType.APPLICATION_JSON)
				.post(ClientResponse.class);
        if (response.getClientResponseStatus() == ClientResponse.Status.OK) {
        	String output = response.getEntity(String.class);

        	JSONObject json = new JSONObject(output);
        	if (!json.has("current_observation"))
        		throw new Exception("Invalid  format!");
        	json = json.getJSONObject("current_observation");
        	weather = new Weather();
        	JSONObject loc = json.getJSONObject("display_location");
        	weather.setPlace(loc.getString("full"));
        	weather.setLatitude(loc.getString("latitude"));
        	weather.setLongitude(loc.getString("longitude"));
        	
        	weather.setWeather(json.getString("weather"));
        	weather.setTemperature(json.getString("temperature_string"));
        	weather.setWind(json.getString("wind_string"));
        	weather.setWindDirection(json.getString("wind_dir"));
        	weather.setIconUrl(json.getString("icon_url"));
        }
        return weather;
	}
	
	@GET
	@Path("{screenid}")
	@Produces(MediaType.TEXT_HTML)
	public Viewable screen(@Context HttpServletRequest request,
			@PathParam("screenid") int screenId) throws Exception {
		SimpleDateFormat formatter = new SimpleDateFormat("E, yyyy-MM-dd 'at' h:m:s");
		Date now = new Date();
		request.setAttribute("time", formatter.format(now));
		
		Screen s = manager.get(screenId);
		
		if (s != null && s.getServiceType() == Service.WEATHER) {	
			request.setAttribute("weather", getWeather());
			return new Viewable("/WEB-INF/jsp/weather.jsp", null);
		}
		if (s != null && s.getServiceType() == Service.USERS_SUMMARY) {
			request.setAttribute("users", getUsers());
			return new Viewable("/WEB-INF/jsp/user.jsp", null);			
		}
		if (s != null && s.getServiceType() == Service.TRELLO) {
			request.setAttribute("trello", getTrello());
			return new Viewable("/WEB-INF/jsp/trello.jsp", null);			
		}
		return new Viewable("/WEB-INF/jsp/no_service.jsp", null);
	}
	
	@Path("/manage")
	@GET
	@Produces(MediaType.TEXT_HTML)
	public Viewable manage(@Context HttpServletRequest request) throws Exception {
		SimpleDateFormat formatter = new SimpleDateFormat("E, yyyy-MM-dd 'at' h:m:s");
		Date now = new Date();
		request.setAttribute("time", formatter.format(now));

		request.setAttribute("screens", manager.getAll());
		request.setAttribute("services", manager.getServices());
		
		return new Viewable("/WEB-INF/jsp/manage.jsp", null);
	}
	
	@Path("/manage")
	@POST
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	@Produces(MediaType.TEXT_HTML)
	public Viewable change(@Context HttpServletRequest request,
			@FormParam("screen") int screenId,
			@FormParam("service") int serviceType) throws Exception {
		Screen s = manager.get(screenId);
		if (s != null)
			s.setServiceType(serviceType);
		
		return manage(request);
	}
	
	
}
